﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
namespace GCELibrary.Current
{
    /// <summary>
    /// 报告处理基类
    /// </summary>
    public abstract class WarnBase : Exception
    {//这里采用装饰模式
        #region
        /// <summary>
        /// 报告处理逻辑
        /// </summary>
        public WarnBase InnerWarn { get; protected set; }
        public WarnBase()
        {
        }
        public WarnBase(string message) : base(message) { }
        public WarnBase(WarnBase innerWarn)
            : base(innerWarn.Message)
        {
            this.InnerWarn = innerWarn;
        }
        public WarnBase(Exception ex) : base(ex.Message, ex) { }
        public WarnBase(int code)
            : base(_GetWarnMessageByCode(code))
        {
        }

        /// <summary>
        /// 提示报告 
        /// </summary>
        public virtual void Alert()
        {
            if (this.InnerWarn != null)
                this.InnerWarn.Alert();
        }
        /// <summary>
        /// 获取报告代码对应的报告内容
        /// </summary>
        /// <param name="code">提示代码</param>
        /// <returns></returns>
        public virtual string GetWarnMessageByCode(int code)
        {
            return _GetWarnMessageByCode(code);
        }
        /// <summary>
        /// 获取报告代码对应的报告内容
        /// </summary>
        /// <param name="code">提示代码</param>
        /// <returns></returns>
        private static string _GetWarnMessageByCode(int code)
        {
            return null;//直接返回，因为暂时没有报告代码
            return code.ToString();
        }

        /// <summary>
        /// 执行错误处理，本方于仅限在Application_Error调用
        /// </summary>
        /// <param name="ex"></param>
        public static void Execute(Exception ex)
        {
            if (ex is WarnBase)
            {
                try
                {
                    ((WarnBase)ex).Alert();
                }
                catch
                {
                    throw;
                }
            }
        }

        public override string ToString()
        {
            if (InnerException != null)
            {
                return InnerException.ToString();
            }

            return base.ToString();
        }
        #endregion
    }
    /// <summary>
    /// 页面报告参数类
    /// </summary>
    public class PageWarnParameter
    {
        #region 属性
        /// <summary>
        /// 转到页面
        /// </summary>
        public string DoPage { get; set; }
        /// <summary>
        /// 提示图标
        /// </summary>
        public WarnIcon Icon { get; set; }
        /// <summary>
        /// 页面转移类型
        /// </summary>
        public WarnLink Link { get; set; }
        /// <summary>
        /// 消息标题
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        /// 提示内容
        /// </summary>
        public string Message { get; set; }
        /// <summary>
        /// 是否在当前页提示信息
        /// 如果是：则页面跳转为Server.Transfer方式
        /// 如果非：刚页面跳转为Response.Redirect方式
        /// </summary>
        public bool TransferType { get; set; }
        /// <summary>
        /// 报告页面
        /// </summary>
        public string AlertPage { get; set; }
        /// <summary>
        /// 报告级别
        /// </summary>
        public WarnLevel Level { get; set; }
        /// <summary>
        /// 错误代码
        /// </summary>
        public Nullable<int> WarnCode { get; set; }
        /// <summary>
        /// 脚本提示模式
        /// </summary>
        public bool JscriptMode { get; set; }
        bool _endResponse = false;
        /// <summary>
        /// 是否结束当前输出
        /// </summary>
        public bool EndResponse { get { return !_endResponse; } set { _endResponse = !value; } }
        #endregion
    }
    /// <summary>
    /// 报告提示
    /// </summary>
    public class PageWarn : WarnBase
    {
        #region
        public PageWarnParameter Parameter = null;//参数
        public PageWarn(PageWarnParameter param)
        {
            InitParameter(param);
        }
   
 
 
        /// <summary>
        /// 初始化参数
        /// </summary>
        /// <param name="param"></param>
        protected virtual void InitParameter(PageWarnParameter param)
        {
            if (param == null) throw new ArgumentNullException("param", "参数不能为null值");
            this.Parameter = param;
            this.Parameter.AlertPage = this.Parameter.AlertPage.EmptyString("~/warn.aspx");
            this.Parameter.Message = this.Parameter.WarnCode.HasValue ? GetWarnMessageByCode(this.Parameter.WarnCode.Value) : this.Parameter.Message;

        }
        /// <summary>
        /// 发出提示
        /// </summary>
        public override void Alert()
        {
            base.Alert();
            if (Parameter.JscriptMode)
                DoAlert();
            else
                DoAlertPage(CreateUrl(), Parameter.EndResponse);
        }
        /// <summary>
        /// 转到页面
        /// </summary>
        protected virtual string CreateUrl()
        {


            string msg = this.Parameter.WarnCode.HasValue ? GetWarnMessageByCode(this.Parameter.WarnCode.Value) : this.Parameter.Message;
            //url编码
            string eMessage = HttpUtility.UrlEncode(msg);//消息内容
            string eMode = HttpUtility.UrlEncode(this.Parameter.Link.ToString());//页面连接方式
            string eType = HttpUtility.UrlEncode(this.Parameter.Icon.ToString());//提示页面的图标
            string eTitle = string.Empty;//标题
            if (!string.IsNullOrEmpty(this.Parameter.Title))
                eTitle = HttpUtility.UrlEncode(this.Parameter.Title);

            //如果链接方式为转到本页，则获取当前面的url进行为跳转页面
            if (this.Parameter.Link == WarnLink.Current)
            {
                if (HttpContext.Current == null)
                    throw new NullReferenceException("HttpContext.Current未将对象引用设置到对象的实例");
                this.Parameter.DoPage = HttpContext.Current.Request.Url.ToString();
            }
            string path = "";
            if (string.IsNullOrEmpty(this.Parameter.DoPage) && this.Parameter.Link != WarnLink.Current)
            {//没有跳转页面
                path = string.Format("{0}?Content={1}&LinkType={2}&ExpType={3}&Title={4}", this.Parameter.AlertPage, eMessage, eMode, eType, eTitle);
            }
            else
            {//存在跳转页面
  
                string ePage = HttpUtility.UrlEncode(this.Parameter.DoPage);
                path = string.Format("{0}?Content={1}&LinkType={2}&Page={3}&ExpType={4}&Title={5}", this.Parameter.AlertPage, eMessage, eMode, ePage, eType, eTitle);

            }
            return path;
        }
        /// <summary>
        /// 转到指定页面
        /// </summary>
        /// <param name="page"></param>
        protected virtual void DoAlertPage(string url,bool endResponse)
        {
            try
            {
                if (this.Parameter.TransferType)
                    HttpContext.Current.Server.Transfer(url, endResponse);
                else
                    HttpContext.Current.Response.Redirect(url, endResponse);
            }
            catch { throw; }
        }
        /// <summary>
        /// 重载
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            if (!string.IsNullOrEmpty(Parameter.Message))
            {
                return Parameter.Message;
            }
            else if (this.InnerWarn != null && !string.IsNullOrEmpty(this.InnerWarn.Message))
            {
                return this.InnerWarn.Message;
            }
            else if (this.InnerException != null)
            {
                return this.InnerException.ToString();
            }
            else
            {
                throw new ApplicationException();
            }
        }
        /// <summary>
        /// 获取报告代码
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public override string GetWarnMessageByCode(int code)
        {
            string result = base.GetWarnMessageByCode((int)code);
            if (string.IsNullOrEmpty(result))
            {
                var _code=WarnCode.UnKnow;
                if (code.Convert<WarnCode>(out _code))
                {
                    return _code.GetDescription().Name;
                }
                else
                {
                    return null;
                }
            }
            return result;
        }

        protected virtual void DoAlert()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<script>");
            sb.AppendFormat("var warnMsg='{0}';", Parameter.Message);
            sb.Append("alert(warnMsg);");




            if (!string.IsNullOrEmpty(Parameter.DoPage))
            {
                sb.AppendFormat("window.location='{0}';", Parameter.DoPage);
                sb.AppendFormat("top.location='{0}';", Parameter.DoPage);
            }
            else if (Parameter.Link== WarnLink.GoLogin)
            {
                sb.AppendFormat("window.location='{0}';", Parameter.DoPage);
                sb.AppendFormat("top.location='{0}';", Parameter.DoPage);
            }
            else if (Parameter.Link == WarnLink.Current)
            {
                sb.AppendFormat("window.location='{0}';", HttpContext.Current.Request.Url.ToString());
            }
            else if (Parameter.Link == WarnLink.Close)
            {
                sb.AppendFormat("window.close();", HttpContext.Current.Request.Url.ToString());
            }
            else
                sb.AppendFormat("window.history.back();", Parameter.DoPage);
            sb.Append("</script>");
            HttpContext.Current.Response.Write(sb.ToString());
            HttpContext.Current.Response.End();
        }
        #endregion
    }
    /// <summary>
    /// 默认的页面报告生成器
    /// </summary>
    public class WarnFactory
    {
        private string _alertPage = null;
        public WarnFactory()
        {
        }
        public WarnFactory(string alertPage)
        {
            this._alertPage = alertPage;
        }
 

        #region Wran
        /// <summary>
        /// 创建一个报告类
        /// </summary>
        /// <param name="message">消息内容</param>
        /// <param name="icon">图标</param>
        /// <param name="link">连接方式</param>
        /// <returns></returns>
        public virtual WarnBase CreateWarn(string message, WarnIcon icon, WarnLink link)
        {
            return CreateWarn(new PageWarnParameter()
            {
                Message = message,
                Icon = icon,
                Link = link,
                AlertPage=this._alertPage
                
            });
        }
        /// <summary>
        /// 创建一个报告类
        /// </summary>
        /// <param name="message">消息内容</param>
        /// <param name="icon">图标</param>
        /// <param name="link">连接方式</param>
        /// <returns></returns>
        public virtual WarnBase CreateWarn(string message, WarnIcon icon, string page)
        {
            return CreateWarn(new PageWarnParameter()
            {
                Message = message,
                Icon = icon,
                DoPage = page,
                Link = WarnLink.GoPage,
                AlertPage = this._alertPage
            });
        }

        /// <summary>
        /// 创建一个报告类
        /// </summary>
        /// <param name="message">消息内容</param>
        /// <returns></returns>
        public virtual WarnBase CreateWarn(string message)
        {
            return CreateWarn(new PageWarnParameter()
            {
                Message = message,
                AlertPage = this._alertPage
            });
        }
        /// <summary>
        /// 创建一个报告类
        /// </summary>
        /// <param name="message">消息</param>
        /// <param name="level">等级</param>
        /// <returns></returns>
        public virtual WarnBase CreateWarn(string message, WarnLevel level)
        {
            return CreateWarn(new PageWarnParameter()
            {
                Message = message,
                Level = level,
                AlertPage = this._alertPage
            });
        }


        /// <summary>
        /// 创建一个报告类
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        public virtual WarnBase CreateWarn(PageWarnParameter param)
        {
             param.AlertPage=this._alertPage;
             return new PageWarn(param);
        }
        
        /// <summary>
        /// 创建一个报告类
        /// </summary>
        /// <param name="innerWarn">内部报告</param>
        /// <returns></returns>
        public virtual WarnBase CreateWarn(WarnBase innerWarn)
        {
            return new PageWarn(
                new PageWarnParameter()
                {
                    Message = innerWarn.Message,
                    AlertPage = this._alertPage,
                });
        }
        /// <summary>
        /// 创建一个报告类
        /// </summary>
        /// <param name="ex">异常</param>
        /// <returns></returns>
        public virtual WarnBase CreateWarn(Exception ex)
        {
            return new PageWarn(new PageWarnParameter()
            {
                Message = ex.ToString(),
                AlertPage = this._alertPage

            });
        }
        /// <summary>
        /// 创建一个报告类
        /// </summary>
        /// <param name="key">报告代码</param>
        /// <returns></returns>
        public virtual WarnBase CreateWarn(WarnCode key)
        {
            if (key == WarnCode.LoginTimeOut)
            {
                return CreateWarn(new PageWarnParameter()
                {
                    Link = WarnLink.GoLogin,
                    WarnCode = (int)key,
                    AlertPage = this._alertPage

                });
            }
            else
            {
                return new PageWarn(new PageWarnParameter()
                {
                     WarnCode=(int)key,
                     AlertPage = this._alertPage,
                });
            }

            
        }
    

        #endregion
    }

 



    /// <summary>
    /// 页面提示格式化连接
    /// </summary>
    public class  WarnMessageLink
    {
        bool addOtherFlag = false;
        public WarnMessageLink(string content)
        {
            _msgList = new List<KeyValuePair<string, string>>();
            _AddWarnMessageLink(content, null);
            
        }
        List<KeyValuePair<string, string>> _msgList = null;
        private void _AddWarnMessageLink(string content, string url)
        {
            _msgList.Add(new KeyValuePair<string, string>(content, url));
        }


        /// <summary>
        /// 添加一个连接
        /// </summary>
        /// <param name="content"></param>
        /// <param name="url"></param>
        public void AddWarnMessageLink(string content, string url)
        {
            if(!addOtherFlag)
            {
                _AddWarnMessageLink("您还可以进行如下操作:", null);
                addOtherFlag = true;
            }
            _AddWarnMessageLink( content,  url);
    
        }
        /// <summary>
        /// 获取格式化的消息
        /// </summary>
        /// <returns></returns>
        public string GetFormatMessage()
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            int i = -1;
            foreach (var l in _msgList)
            {
                if (l.Value == null)
                    sb.AppendFormat("<tr><td>{0}</td></tr>", l.Key, l.Value);
                else
                {
                    sb.AppendFormat("<tr><td>{2})、{0} <a href='{1}'>请点击</a></td></tr>", l.Key, l.Value,i);
                }
                i++;
            }
            return string.Format("<table>{0}</table>", sb.ToString());
        }
        public override string ToString()
        {
            return GetFormatMessage();
        }
    }
}
